home *** CD-ROM | disk | FTP | other *** search
- //
- // SELECT.h -- useful macros
- // Written and copyright 1994, 1995, 1996 by Raf Schietekat.
- // Version 1995-03-22. All rights reserved.
- // This notice may not be removed from this source code.
- //
- // This code is included in the MiscKit by permission from the author
- // and its use is governed by the MiscKit license, found in the file
- // "LICENSE.rtf" in the MiscKit distribution. Please refer to that file
- // for a list of all applicable permissions and restrictions.
- //
-
- // These macros do not use the "MISC" prefix because that would ruin
- // their elegance. If they cause you grief, just #define MISC_SKIP_SELECT
- // before importing the MiscBase.h or misckit.h...
-
- /*
- WARNING!!!
- The number in E_ENDSELECT* should now include E_IFDEFAULT.
- Please adapt your code to comply (you'll be notified by a compilation failure
- if your code is affected).
- (E_SELECT/E_IFDEFAULT was not in the MiscKit before, so the change
- is transparent to its users.)
- */
-
- /*
- Author: Raf Schietekat (RfSchtkt@maze.ruca.ua.ac.be on 1995-03-11)
- Copyright: Raf Schietekat, 1994, 1995
- License:
- - You may use this code in your product without any fee, and you also don't
- have to mention your use of this code.
- - You may not change this file. If you want to, propose a change, and I
- may agree to it. My purpose is to have only one version
- of this code around, and to always have the best version :-).
- - You should provide this code to anyone who asks for it, for free,
- or covering the cost of the media only, and the recipient will be bound
- by the same licence terms.
- - This license does not limit my use of this code in any other way.
- License applications:
- - GNU projects may use this file as long as any changes are made only in
- the form of #undef/#define pairs external to this file, regardless of the
- general GNU license terms. This file does not become part of GNU, and
- the owner of the GNU license may not prohibit anyone from using this file
- in a private project.
- - Likewise, for the MiscKit in the NEXTSTEP world, the MiscKit administrator
- may at most prepend an introductory comment to this file, but he should not
- modify anything else. This file does not become part of the MiscKit
- (except to the extent that it will remain available), and the MiscKit's
- administrator may not prohibit anyone from extracting this file
- from the MiscKit, removing the introductory comment by the MiscKit's
- administrator, and using this file in a private project without
- recognising the MiscKit.
- - These are not really additions to the license, merely clarifications,
- and similar rules apply to anyone else who redistributes this file.
- Guarantee: every imagineable disclaimer applies.
- Version:
- 1995-03-22: #define E_INTERMEZZO(c) E_IF(((c),0)) 0, not E_IF((c),0)
- 1995-03-11
- Maturity:
- I use SELECT in nearly every source file I write; it works like a charm
- Acknowledgements: so far, only the author has contributed to this code
- */
-
- /*
- Applicability: general C (pre-ANSI, ANSI, Objective-C, C++).
- To try the examples, transform !* *! into ... (ahem, I almost made this
- file unusable), and maybe also the // which introduces a trailing comment in
- Objective-C and C++ compilers.
- */
-
- /********** a better selector **********/
-
- #define SELECT {if(0){
- #define IF(c) }else if(c){
- #define IFDEFAULT }else { /*optional*/
- #define ENDSELECT }}
- #define IFNOT(c) IF(!(c))
- #define INTERMEZZO(c) IF(((c),0))
- /*
- You can use this as any {} block, both as a whole (e.g., for(;;) SELECT...),
- and within the clauses (you can define local variables).
- Contrived example (notice my plug of indentation style):
- >>>>>
- #import <stdio.h>
- #import "SELECT.h"
-
- int main(int argc,char *argv[]){
- !*var*! int a=5,b=4;
- SELECT // this is always used to start the construct
- printf("Don't put any code here: it will never be executed!");
- IF(a==b)
- // the prototypical case: if the condition is true
- // the block is executed and the construct is exited, otherwise
- // the next clause is tested
- !*var*! int c; // you can declare local variables as in any {} block
- c=a+b; printf("a=b, a+b=%i\n",c);
- INTERMEZZO(printf("a=%i, b=%i\n",a,b))
- // will unconditionally execute and always proceed to the next test
- printf("Don't put any code here: it will never be executed!");
- INTERMEZZO(printf("Multiple commands go into multiple INTERMEZZOs.\n"))
- printf("Don't put any code here: it will never be executed!");
- INTERMEZZO((printf("(Or you can use"),printf(" the comma operator,\n")))
- INTERMEZZO(printf("but that's a bit awkward with the extra ().)\n"))
- IFNOT(a<b) SELECT // to show appropriate nesting
- IF(b<0) printf("b<0\n");
- IFDEFAULT printf("Do stuff for 0<=b<=a\n");
- ENDSELECT
- IFDEFAULT
- printf("IFDEFAULT must come last but is optional\n");
- ENDSELECT // always end the construct with this ``keyword''
- exit(0);
- }
- <<<<<
- */
-
-
- /********** similarly for E_xpressions (less elegant, though) **********/
-
- #define E_SELECT ((0)?(0
- #define E_IF(c) ):((c)?(
- #define E_IFDEFAULT ): ( /*required*/
- #define E_ENDSELECT1 ))
- #define E_ENDSELECT2 )))
- #define E_ENDSELECT3 ))))
- #define E_ENDSELECT4 )))))
- #define E_ENDSELECT5 ))))))
- #define E_ENDSELECT6 )))))))
- #define E_ENDSELECT7 ))))))))
- #define E_ENDSELECT8 )))))))))
- #define E_ENDSELECT9 ))))))))))
- #define E_ENDSELECT10 )))))))))))
- #define E_ENDSELECT11 ))))))))))))
- #define E_ENDSELECT12 )))))))))))))
- #define E_ENDSELECT13 ))))))))))))))
- #define E_ENDSELECT14 )))))))))))))))
- #define E_ENDSELECT15 ))))))))))))))))
- #define E_ENDSELECT16 )))))))))))))))))
- #define E_ENDSELECT17 ))))))))))))))))))
- #define E_ENDSELECT18 )))))))))))))))))))
- #define E_ENDSELECT19 ))))))))))))))))))))
- #define E_ENDSELECT20 )))))))))))))))))))))
- #define E_IFNOT(c) E_IF(!(c))
- #define E_INTERMEZZO(c) E_IF(((c),0)) 0
- /*
- Designed to mirror the SELECT family, with these exceptions:
- - The content of the clauses is now a value, not the content of a block.
- - Unlike IFDEFAULT above, E_IFDEFAULT cannot be omitted.
- - E_ENDSELECT* requires specification of the total number
- of clauses (including E_INTERMEZZO, as its definition reveals).
- If you want more than 20 clauses, define additional macros
- (externally to this file), and begin to wonder about your programming style.
- Contrived example (notice my plug of indentation style):
- >>>>>
- #import <stdio.h>
- #import "SELECT.h"
-
- int main(int argc,char *argv[]){
- !*var*! int minValue=3,value=1000,maxValue=6;
- printf("%i constrained to [%i,%i] is %i.\n",
- value,
- minValue,maxValue,
- E_SELECT
- E_IFNOT(minValue<=value ) minValue
- E_IFNOT( value<=maxValue) maxValue
- E_IFDEFAULT value
- E_ENDSELECT3
- );
- exit(0);
- }
- <<<<<
- */
-
-
- /***** overriding fall-through as the default in a switch statement *****/
-
- #define CASE break;case
- #define DEFAULT break;default
- /*
- Contrived example (notice my plug of indentation style):
- switch(n){
- case 0: printf("always use case, not CASE, for the first clause\n");
- // to avoid a spurious warning by overzealous compilers
- CASE 1: printf("isn't the absence of ``break'' a liberation?\n");
- DEFAULT: printf("and that's the last one\n");
- }
- */
-